package com.link.base.base.consumer.controller;

import com.link.base.user.model.CoreUser;
import com.link.base.base.consumer.model.PortalAccntLine;
import com.link.base.base.consumer.model.PortalAccntLineTemporary;
import com.link.base.base.consumer.service.PortalAccntLineService;
import com.link.base.base.consumer.service.PortalAccntLineTemporaryService;
import com.link.base.base.opty.model.Opty;
import com.link.base.base.opty.service.OptyService;
import com.link.base.base.sms.service.SmsSendService;
import com.link.core.cllog.LCLogger;
import com.link.core.basic.annotations.JsonParam;
import com.link.core.basic.controller.BasicController;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.ImportColumn;
import com.link.core.basic.query.QueryParams;
import com.link.core.basic.service.BasicService;
import com.link.core.basic.service.ServiceException;
import com.link.core.basic.service.KeyGenerateService;
import com.link.core.modules.export.ExportFactory;
import com.link.core.modules.export.ExportWriter;
import com.link.core.modules.export.exception.WriteExportFileException;
import com.link.core.modules.imports.ImportReader;
import com.link.core.modules.imports.ImportsFactory;
import com.link.core.util.SessionUtil;
import com.link.core.util.StringUtils;
import com.link.core.util.UserUtil;
import com.link.ext.basic.model.BasicBaseModel;
import com.link.ext.basic.model.BasicExtModel;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 消费者临时表相关服务
 * @author  yipeng.zhu@hand-china.com
 * @date:   2018/11/2 15:24
 * @version 1.0
 */

@Controller
@RequestMapping("/link/accntLineTemporary")
public class AccntLineTemporaryController extends BasicController<PortalAccntLineTemporary> {
    @Resource
    private PortalAccntLineTemporaryService portalAccntLineTemporaryService;
    @Resource
    private PortalAccntLineService portalAccntLineService;
    @Resource
    private OptyService optyService;
    @Resource
    private SmsSendService smsSendService;
    @Resource
    private KeyGenerateService keyGenerateService;

    @Override
    public BasicService<PortalAccntLineTemporary> getBasicService() throws Exception {
        if (portalAccntLineTemporaryService != null) {
            return portalAccntLineTemporaryService;
        }
        throw new ServiceException("PUBLIC-005");
    }

    /**
     * 获取当前属性下的值
     * @author      yipeng.zhu@hand-china.com
     * @param       exportData
     * @param       field
     * @return
     * @exception
     * @date        2018/11/2 15:39
     * @version     1.0
     */
    public static Object getProperty(Object exportData, String field)
            throws IllegalAccessException, InvocationTargetException {
        Object colData = "";
        try {
            colData = PropertyUtils.getSimpleProperty(exportData, field);
        } catch (NoSuchMethodException e) {
            if (exportData instanceof BasicBaseModel) {
                List<BasicExtModel> extList = ((BasicBaseModel) exportData).getExtList();
                if (extList != null) {
                    for (BasicExtModel ext : extList) {
                        if (StringUtils.equals(field, ext.getName())) {
                            colData = ext.getValue();
                            break;
                        }
                    }
                }
            } else {
                LCLogger.withException(e);
            }
        }
        return colData;
    }

    protected static <T> Object parseValueWithType(String value, Class<?> type) {
        Object result = null;
        String doubleType = "java.lang.Double";
        try { // 根据属性的类型将内容转换成对应的类型
            if (Boolean.class == type) {
                result = Boolean.parseBoolean(value);
            } else if (Byte.class == type) {
                result = Byte.parseByte(value);
            } else if (Short.class == type) {
                result = Short.parseShort(value);
            } else if (Integer.class == type) {
                result = Integer.parseInt(value);
            } else if (Long.class == type) {
                result = Long.parseLong(value);
            } else if (Float.class == type) {
                result = Float.parseFloat(value);
            } else if (Double.class == type) {
                result = Double.parseDouble(value);
            } else if (Class.forName(doubleType) == type) {
                result = Double.parseDouble(value);
            } else {
                result = (Object) value;
            }
        } catch (Exception e) {
            // 把异常吞掉直接返回null
        }
        return result;
    }
    /**
     *  导入线下消费者--临时表
     * @author      yipeng.zhu@hand-china.com
     * @param       entity
     * @param       qps
     * @param       session
     * @param       request
     * @param       response
     * @exception
     * @date        2018/11/2 16:12
     * @version     1.0
     */

    @Override
    @RequestMapping(value = "/importExcelData")
    @ResponseBody
    public Map<String, Object> importData(@JsonParam PortalAccntLineTemporary entity,@JsonParam QueryParams qps, HttpSession session,
                                          HttpServletRequest request, HttpServletResponse response) {

        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            ImportReader importReader = ImportsFactory.newInstance(qps, request);
            List<PortalAccntLineTemporary> list = (List<PortalAccntLineTemporary>) importReader
                    .readList(entity.getClass());
            if (list.size() < 1) {
                result.put("success", false);
                result.put("result", "未检测到导入数据");
                result.put("detailMessage", "未检测到导入数据");
                return result;
            }
            portalAccntLineTemporaryService.importExcelCheck(list, qps, request.getParameter("acctChannel"));
            import07ExcelData(list, qps, request);
            qps.setPageFlag(false);

            CoreUser landedUser = UserUtil.getUser();
            PortalAccntLineTemporary t = (PortalAccntLineTemporary) BasicModel.transformClass(entity, qps);
            t.setCreatedBy(landedUser.getId());
            t.setAcctType("ChannelConsumer");
            t.setAcctChannel(request.getParameter("acctChannel"));
            t.setAccntValidate("N");
            int fail = portalAccntLineTemporaryService.queryByExamplePage(t).size();
            t.setAccntValidate("Y");
            int success = portalAccntLineTemporaryService.queryByExamplePage(t).size();
            result.put("success", true);
            result.put("total", list.size());
            result.put("suc", success);
            result.put("fail", fail);
        } catch (ServiceException e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
            result.put("detailMessage", e.getMessage());
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 插入临时表
     * @author yipeng.zhu@hand-china.com
     * @param list
     * @param qps
     * @param request
     * @throws Exception
     * @time 2018-5-21
     */

    protected void import07ExcelData(List<PortalAccntLineTemporary> list, QueryParams qps, HttpServletRequest request)
            throws Exception {
        CoreUser landedUser = UserUtil.getUser();
        for (int i = 0; list != null && i < list.size(); i++) {
            PortalAccntLineTemporary record = list.get(i);
            record.setAcctChannel(request.getParameter("acctChannel"));
            record.setAcctType("ChannelConsumer");
            record.setOrgId(landedUser.getOrgId());
            portalAccntLineTemporaryService.insert(record);
        }
    }

    /**
     * 导出效验后消费者 excel 数据
     * @author      yipeng.zhu@hand-china.com
     * @return
     * @exception
     * @date        2018/11/2 16:39
     * @version     1.0
     */

    @Override
    @RequestMapping(value = "/exportExcelData")
    @ResponseBody
    public Map<String, Object> exportData(@JsonParam PortalAccntLineTemporary entity,@JsonParam QueryParams qps, HttpSession session,
                                          HttpServletRequest request, HttpServletResponse response) {

        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            qps.preDealSecurity(request);
            qps.setPageFlag(false);
            PortalAccntLineTemporary t = (PortalAccntLineTemporary) BasicModel.transformClass(entity, qps);
            beforQueryAllOrExample(t, request);
            beforQueryExample(t, request);
            ExportWriter exportWriter;
            // 解析xlsx
            exportWriter = ExportFactory.Excel2007Instance(qps);
            CoreUser landedUser = UserUtil.getUser();
            t.setAcctType("ChannelConsumer");
            t.setAcctChannel(request.getParameter("acctChannel"));
            t.setCreatedBy(landedUser.getId());
            while (!qps.getStopExport()) {
                beforQueryAllOrExample(t, request);
                beforQueryExample(t, request);
                t.setOrgId(landedUser.getOrgId());
                List<PortalAccntLineTemporary> list = portalAccntLineTemporaryService.queryByExamplePage(t);
                if (qps.getPage() == 1) {
                    qps.setTotal(t.getTotal());
                }
                if ("Y".equals(qps.getExportCurrentPage())) {
                    break;
                }
                exportWriter.wirteData(list);
                t.setPage(qps.getPage());
                t.setTotalFlag(qps.getTotalFlag());
            }
            result.put("success", true);
            result.put("url", exportWriter.getUrlPath());
        } catch (ServiceException e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
            result.put("detailMessage", e.getMessage());
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 删除临时的数据
     *
     * @param entity
     * @param qps
     * @param session
     * @param request
     * @param response
     * @return
     */

    @RequestMapping(value = "/exportExcelDelete")
    @ResponseBody
    public Map<String, Object> exportExcelDelete(@JsonParam PortalAccntLineTemporary entity,@JsonParam QueryParams qps, HttpSession session,
                                                 HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);

        try {
            PortalAccntLineTemporary t = (PortalAccntLineTemporary) BasicModel.transformClass(entity, qps);
            CoreUser landedUser = UserUtil.getUser();
            t.setAcctType("ChannelConsumer");
            t.setAcctChannel(request.getParameter("acctChannel"));
            if (landedUser != null) {
                t.setCreatedBy(landedUser.getId());
            }
            portalAccntLineTemporaryService.exportExcelDelete(t);
            result.put("success", true);
        } catch (Exception e) {
            result.put("success", false);

            LCLogger.withException(e);
        }
        return result;

    }


    /**
     * 提交效验通过的数据
     * @author      yipeng.zhu@hand-china.com
     * @param       entity
     * @return
     * @exception
     * @date        2018-5-21
     * @version     1.0
     */
    @RequestMapping(value = "/exportExcelCommit")
    @ResponseBody
    public Map<String, Object> exportExcelCommit(@JsonParam PortalAccntLineTemporary entity,@JsonParam QueryParams qps, HttpSession session,
                                                 HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            qps.preDealSecurity(request);
            qps.setPageFlag(false);
            PortalAccntLineTemporary t = (PortalAccntLineTemporary) BasicModel.transformClass(entity, qps);
            beforQueryAllOrExample(t, request);
            beforQueryExample(t, request);
            CoreUser landedUser = UserUtil.getUser();
            t.setAcctType("ChannelConsumer");
            t.setAcctChannel(request.getParameter("acctChannel"));
            t.setCreatedBy(landedUser.getId());
            t.setAccntValidate("Y");
            List<PortalAccntLineTemporary> list = portalAccntLineTemporaryService.queryByExamplePage(t);
            List<PortalAccntLine> contentlist = changeTypeContent(list, qps, entity);
            //导入效验通过的数据
            importExcelData(contentlist, qps, request, session);
            String source = "STORE";
            String accntSourceForm = "acctChannel";
            if (source.equals(request.getParameter(accntSourceForm))) {
                // 如果是门店的话，添加一条接待记录
                for (int i = 0; i < contentlist.size(); i++) {
                    addOpty(contentlist.get(i));
                }
            }
            result.put("success", true);
            portalAccntLineTemporaryService.exportExcelDelete(t);
        } catch (Exception e) {
            result.put("success", false);
            LCLogger.withException(e);
        }
        return result;

    }

    private void addOpty(PortalAccntLine accntLine) {
        try {
            Opty opty = new Opty();
            // 客户id
            opty.setAccntId(accntLine.getId());
            // 成单状态
            opty.setDealOrderStatus(accntLine.getxAttr67());
            opty.setLoginCorpId(accntLine.getLoginCorpId());
            optyService.insert(opty);
        } catch (Exception e) {
            LCLogger.withException(e);
        }
    }

    /**
     * 正式表(lnk_accnt)插入数据
     * @author      yipeng.zhu@hand-china.com
     * @param       list
     * @param       qps
     * @param       request
     * @return
     * @exception
     * @date        2018/11/2 15:36
     * @version     1.0
     */
    protected void importExcelData(List<PortalAccntLine> list, QueryParams qps, HttpServletRequest request, HttpSession session)
            throws Exception {
        String type = request.getParameter("type");
        Long sendSmsId = 0L;
        String sms = "sms";
        if (StringUtils.equals(type, sms)) {
            sendSmsId = Long.parseLong(SessionUtil.getAttribute("SendSmsId"));
            smsSendService.delBySmsId(sendSmsId);
        }
        PortalAccntLine entity = new PortalAccntLine();
        CoreUser landedUser = UserUtil.getUser();
        for (int i = 0; list != null && i < list.size(); i++) {
            PortalAccntLine record = list.get(i);
            record.setAcctChannel(request.getParameter("acctChannel"));
            record.setAcctType("ChannelConsumer");
            if (landedUser == null) {
                record.setId(0L);
            } else {
                record.setOrgId(landedUser.getOrgId());
            }
            PortalAccntLine existAccnt = portalAccntLineService.queryAccntByCombinCondition(record);
            if (existAccnt != null) {
                Class<?> clz = entity.getClass();
                // 获取类中的所有方法集合
                Method[] methods = clz.getDeclaredMethods();
                // 循环方法集合
                for (Method method : methods) {
                    //判断需要更新的字段
                    for (ImportColumn model : qps.getImportColumns()) {
                        if (("set" + model.getField().toLowerCase()).equals(method.getName().toLowerCase())) {
                            String content = (String) PropertyUtils.getSimpleProperty(record, model.getField());
                            PropertyUtils.setSimpleProperty(existAccnt, model.getField(), content);
                        }
                    }
                }
                if (StringUtils.equals(type, "sms")) {
                    smsSendService.addSendAccontLine(sendSmsId, existAccnt.getId());
                }
                portalAccntLineService.update(existAccnt);
            } else {
                portalAccntLineService.insert(list.get(i));
                if (StringUtils.equals(type, "sms")) {
                    record.setId(keyGenerateService.keyGenerate());
                    smsSendService.addSendAccontLine(sendSmsId, record.getId());
                }
            }
        }
    }


    /**
     * 实体类型转换
     * @author      yipeng.zhu@hand-china.com
     * @param       entity
     * @return
     * @throws WriteExportFileException
     * @date        2019/3/7 20:57
     * @version     1.0
     */
    @SuppressWarnings("null")
    public List<PortalAccntLine> changeTypeContent(List<PortalAccntLineTemporary> contentList, QueryParams qps,
                                                   PortalAccntLineTemporary entity) throws WriteExportFileException {
        List<PortalAccntLine> accntlinelist = new ArrayList<PortalAccntLine>();
        // 循环数据
        for (int i = 0; contentList != null && i < contentList.size(); i++) {
            PortalAccntLine record = new PortalAccntLine();
            PortalAccntLineTemporary exportData = contentList.get(i);
            // 获取当前返回值对象对应的类
            Class<?> clazz = record.getClass();
            int accntLineSize = qps.getImportColumns().size();
            for (int j = 0; j < accntLineSize; j++) {
                ImportColumn colum = qps.getImportColumns().get(j);
                String field = colum.getField();
                // 获取当前返回值对象相关属性值
                Field propertyField;
                Class<?> propertyType = null;
                Object columData = null;
                try {
                    try {
                        propertyField = clazz.getDeclaredField(field);
                        propertyType = propertyField.getType();
                    } catch (NoSuchFieldException e) {
                        LCLogger.withException(e);
                        propertyType = String.class;
                    }
                    columData = getProperty(exportData, field);
                } catch (SecurityException e) {
                    LCLogger.withException(e);
                } catch (IllegalAccessException e) {
                    LCLogger.withException(e);
                } catch (InvocationTargetException e) {
                    LCLogger.withException(e);
                }

                String formatData = "";
                if (columData == null) {
                    formatData = "";
                } else {
                    formatData = columData.toString();
                }
                try {
                    PropertyUtils.setProperty(record, field, parseValueWithType(formatData, propertyType));
                } catch (IllegalAccessException e) {
                    LCLogger.withException(e);
                } catch (InvocationTargetException e) {
                    LCLogger.withException(e);
                } catch (NoSuchMethodException e) {
                    LCLogger.withException(e);
                }

            }
            accntlinelist.add(record);
        }
        return accntlinelist;
    }


}
